package com.example.taxfloatproject20240926.ui.floatrecorder;

import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.PixelFormat;
import android.os.Build;
import android.text.TextUtils;
import android.util.Log;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.widget.LinearLayout;

import androidx.databinding.DataBindingUtil;

import com.example.taxfloatproject20240926.R;
import com.example.taxfloatproject20240926.databinding.PopupControlViewBinding;
import com.example.taxfloatproject20240926.ui.room.CallInterface;
import com.example.taxfloatproject20240926.ui.room.CallRepository;
import com.example.taxfloatproject20240926.ui.utils.Constant;
import com.example.taxfloatproject20240926.ui.MyApp;
import com.example.taxfloatproject20240926.ui.adapter.QueueAdapter;
import com.example.taxfloatproject20240926.ui.bean.CallBean;
import com.example.taxfloatproject20240926.ui.socket.CmdUtils;
import com.example.taxfloatproject20240926.ui.utils.DensityUtil;
import com.example.taxfloatproject20240926.ui.utils.MyAudioManager;
import com.example.taxfloatproject20240926.ui.utils.PlaySound;
import com.example.taxfloatproject20240926.ui.utils.PreferencesUtils;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;

/**
 * Created by zjt on 18-1-19.
 */

public class FloatControlView extends LinearLayout implements CallInterface<CallBean> {
    private Context context;

    private WindowManager.LayoutParams lp;
    private WindowManager windowManager;
    // 移动
    private float downX, downY;
    private float moveX, moveY;
    // 控制
    private boolean isShowing = false;

    long time1;
    long time2;

    private FloatControlViewModel floatControlViewModel;
    private boolean isScroll;
    PopupControlViewBinding binding;

    private OnSureClickListener onSureClickListener;

    private OnOpenSetActivityListener openSetActivityListener;

    private List<CallBean> callBeanList = new ArrayList<>();
    private CallBean callBean;
    private QueueAdapter adapter;

    private CallRepository mCallRepository;

    public void setOpenSetActivityListener(OnOpenSetActivityListener openSetActivityListener) {
        this.openSetActivityListener = openSetActivityListener;
    }

    public FloatControlView(Context context) {
        this(context, null, null);
    }

    public FloatControlView(Context context,
                            OnClickCallback onClickCallback,
                            FloatControlViewModel.OnVisibleChangeListener onVisibleChangeListener) {
        super(context);
        this.context = context;
        windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
        binding = DataBindingUtil.inflate(LayoutInflater.from(context),
                R.layout.popup_control_view, this, false);
        floatControlViewModel = new FloatControlViewModel(context, binding, onClickCallback,
                onVisibleChangeListener);
        binding.setControlViewModel(floatControlViewModel);
        addView(binding.getRoot());
        initLayoutParams();
        initView();
        initEvent();
        initRepository();
        mCallRepository.queryAll();
    }

    private void initRepository(){
        mCallRepository = new CallRepository(context);
        mCallRepository.setCallInterface(this);

    }
    private void initView() {
        getConfig();
        setLayoutParams(binding.imgBg);
        setLayoutParams(binding.llCall);
        setLayoutParams(binding.llConfig);
    }

    private void setLayoutParams(View view) {
        ViewGroup.LayoutParams layoutParams = view.getLayoutParams();
        layoutParams.width = DensityUtil.screenWidth(context);
        layoutParams.height = layoutParams.width;
        view.setLayoutParams(layoutParams);
    }

    public void setOnSureClickListener(OnSureClickListener onSureClickListener) {
        this.onSureClickListener = onSureClickListener;
    }

    private void getConfig() {
        binding.etServerIp.setText(PreferencesUtils.getString(context, Constant.server_ip_key));
        binding.etEvalAddr.setText(PreferencesUtils.getString(context, Constant.eval_addr_key));
        binding.etServerPort.setText(PreferencesUtils.getInt(context, Constant.eval_port_key) + "");
    }

    private void saveConfig() {
        Constant.server_ip = binding.etServerIp.getText().toString().trim();
        Constant.eval_addr = binding.etEvalAddr.getText().toString().trim();
        Constant.eval_port = Integer.parseInt(binding.etServerPort.getText().toString().trim());
        PreferencesUtils.putString(context, Constant.server_ip_key, Constant.server_ip);
        PreferencesUtils.putString(context, Constant.eval_addr_key, Constant.eval_addr);
        PreferencesUtils.putInt(context, Constant.eval_port_key, Constant.eval_port);
    }

    public void hideSet() {
        binding.llConfig.setVisibility(View.GONE);
    }

    public void showSet() {
        binding.llConfig.setVisibility(View.VISIBLE);
    }

    public void showConnect(boolean isConnect) {
        if (isConnect) {
            binding.tvConnect.setVisibility(View.GONE);
        } else {
            binding.tvConnect.setVisibility(View.VISIBLE);
        }
    }

    private boolean initConfig() {
        Constant.server_ip = PreferencesUtils.getString(context, Constant.server_ip_key);
        Constant.eval_addr = PreferencesUtils.getString(context, Constant.eval_addr_key);
        Constant.eval_port = PreferencesUtils.getInt(context, Constant.eval_port_key);
        Constant.yl = PreferencesUtils.getString(context, Constant.yl_key);
        if (!TextUtils.isEmpty(Constant.server_ip)
                && !"127.0.0.1".equals(Constant.server_ip)
        ) {
            return true;
        }
        return false;
    }
    private void initLayoutParams() {
        try {
            lp = new WindowManager.LayoutParams();
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                lp.type = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
            } else {
                lp.type = WindowManager.LayoutParams.TYPE_TOAST;
            }
            lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE |
                    WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;
            lp.gravity = Gravity.START | Gravity.TOP;
            lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
            lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
//            lp.height = DensityUtil.screenHeight(context) - DensityUtil.dip2px(context,50);
            lp.format = PixelFormat.TRANSPARENT;
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @SuppressLint("ClickableViewAccessibility")
    private void initEvent() {
        setOnTouchListener((view, motionEvent) -> {
            switch (motionEvent.getActionMasked()) {
                case MotionEvent.ACTION_DOWN:
                    downX = motionEvent.getRawX();
                    downY = motionEvent.getRawY();
                    isScroll = false;
                    break;
                case MotionEvent.ACTION_MOVE:
                    moveX = motionEvent.getRawX() - downX;
                    moveY = motionEvent.getRawY() - downY;
                    downX += moveX;
                    downY += moveY;
                    if (moveX != 0 || moveY != 0) {
                        isScroll = true;
                    }
                    updateViewPosition();
                    break;
            }
            return false;
        });
        setOnClickListener(view -> {
            if (!isShowing) {
                showCall();
                hideSet();
                isShowing = true;
            } else {
                if (isScroll) {
                    return;
                }
                hideSet();
                hideCall();
                PlaySound.stopAudio();
                binding.imgBg.setVisibility(View.GONE);
                isShowing = false;
            }
        });

        // 点击输入框，弹出输入法
        binding.etServerPort.setOnTouchListener((v, event) -> {
            if (lp == null || binding == null) {
                return false;
            }
            lp.flags = WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;
            windowManager.updateViewLayout(this, lp);
            return false;
        });

        binding.etEvalAddr.setOnTouchListener((v, event) -> {
            if (lp == null || binding == null) {
                return false;
            }
            lp.flags = WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;
            windowManager.updateViewLayout(this, lp);
            return false;
        });

        binding.etServerIp.setOnTouchListener((v, event) -> {
            if (lp == null || binding == null) {
                return false;
            }
            lp.flags = WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;
            windowManager.updateViewLayout(this, lp);
            return false;
        });

        binding.btnLeft.setOnClickListener(view -> time1 = System.currentTimeMillis());
        binding.btnRight.setOnClickListener(view -> {
            time2 = System.currentTimeMillis();
            if (time2 - time1 < 2000) {
                if (openSetActivityListener != null) {
                    openSetActivityListener.onOpenSetActivity();
                }
                showSet();
            }
        });
        binding.btnSure.setOnClickListener(view -> {
            saveConfig();
            hideSet();
            if (!initConfig()) return;
            if (onSureClickListener != null) {
                onSureClickListener.onSureClick(Constant.server_ip, Constant.eval_port);
            }
        });
        binding.btnExit.setOnClickListener(view -> {
            MyApp.getInstance().exit();
        });
        binding.btnClear.setOnClickListener(new DoubleClickListener() {
            @Override
            public void onDoubleClick(View v) {
                Log.i("gjw","doubleclick");
                if (callBeanList !=null && adapter!=null){
                    callBeanList.clear();
                    if (mCallRepository!=null) {
                        mCallRepository.deleteAll();
                    }
                    adapter.setQueLists(callBeanList);
                    adapter.notifyDataSetChanged();
                }
            }
        });
    }

    private void updateViewPosition() {
        lp.x += (int) (moveX);
        lp.y += (int) (moveY);
        windowManager.updateViewLayout(this, lp);
    }

    public WindowManager.LayoutParams getLayoutParams() {
        return this.lp;
    }

    public void setLayoutParams(WindowManager.LayoutParams lp) {
        this.lp = lp;
        if (isShowing)
            windowManager.updateViewLayout(this, lp);
    }

    public void show() {
        if (!isShowing) {
            showCall();
            hideSet();
            isShowing = true;
            windowManager.addView(this, lp);
        }
    }


    public void dismiss() {
        if (isShowing) {
            hideSet();
            hideCall();
            PlaySound.stopAudio();
            binding.imgBg.setVisibility(View.GONE);
            isShowing = false;
            windowManager.removeView(this);
        }
    }


    public void showCall() {
        binding.llCall.setVisibility(View.VISIBLE);
        binding.imgBg.setVisibility(View.VISIBLE);
    }

    public void hideCall() {
        binding.llCall.setVisibility(View.GONE);
        binding.imgBg.setVisibility(View.GONE);
    }

    public FloatControlViewModel getViewModel() {
        return floatControlViewModel;
    }


    public void loadData(String msg) {
        try {
            playSound(R.raw.notify);
            showCall();
            Map<String, String> map = CmdUtils.parseCmd(msg);
            String name = map.get("number");
            String time = map.get("time");
            if (!TextUtils.isEmpty(name) && !TextUtils.isEmpty(time)) {
                if (!TextUtils.isEmpty(time)) {
                    callBean = new CallBean();
                    if (time.contains("_")) {
                        String[] s = time.split("_");
                        if (s != null && s.length > 1) {
                            callBean.setCallInfo(name + "请求帮助 " + s[0] + " " + s[1]);
                            callBean.setTime(s[0] + " " + s[1]);
                        }
                    } else {
                        callBean.setCallInfo(name + "请求帮助 " + time);
                        callBean.setTime(time);
                    }

                    mCallRepository.insertCallData(callBean);
                }
                callBeanList.add(callBean);
                Collections.sort(callBeanList, (callBean, t1) -> t1.getTime().compareTo(callBean.getTime()));
//                Collections.reverse(queueBeanList);
                Log.i("gjw","queueBeanList is " + callBeanList);
                initAdapter(callBeanList);
            }
        } catch (Exception e) {
            Log.e("gjw", "e is " + e.getMessage());
        }
    }

    private void initAdapter(List<CallBean> callBeanList) {
        if (adapter == null) {
            adapter = new QueueAdapter(context, callBeanList);
            binding.tvBianhao.setAdapter(adapter);
        } else {
            adapter.setQueLists(callBeanList);
            adapter.notifyDataSetChanged();
        }
    }

    private boolean playSound(int name) {
        Constant.yl = PreferencesUtils.getString(context, Constant.yl_key);
        if (TextUtils.isEmpty(Constant.yl)) {
            Constant.yl = "100";
        }

        MyAudioManager.setVolume(context, Integer.parseInt(Constant.yl));
        PlaySound.play(context, name, null);
        return true;
    }

    @Override
    public void addSuccess(boolean isAdd) {

    }

    @Override
    public void callList(List<CallBean> calledBeanList) {
        this.callBeanList = calledBeanList;
        initAdapter(callBeanList);
        Log.i("gjw","callBeanList is " + calledBeanList);
    }


    public interface OnSureClickListener {
        void onSureClick(String serverIp, int port);
    }

   public interface OnOpenSetActivityListener{
        void onOpenSetActivity();
    }

}